﻿using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Xml;

namespace SPDevExplorer
{
    public partial class SiteExplorer
    {
        private void AttachEventHandlersToTree()
        {
            _ctlExplorerTree.NodeMouseDoubleClick += _ctlExplorerTree_NodeMouseDoubleClick;
            _ctlExplorerTree.BeforeExpand += _ctlExplorerTree_BeforeExpand;
            _ctlExplorerTree.NodeMouseClick += _ctlExplorerTree_NodeMouseClick;
            _ctlExplorerTree.BeforeLabelEdit += _ctlExplorerTree_BeforeLabelEdit;
            _ctlExplorerTree.AfterLabelEdit += _ctlExplorerTree_AfterLabelEdit;
            _ctlExplorerTree.KeyUp += _ctlExplorerTree_KeyUp;
            _ctlExplorerTree.BeforeSelect += _ctlExplorerTree_BeforeSelect;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <remarks>
        /// 
        /// </remarks>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _ctlExplorerTree_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            try
            {
                SetPropertiesWindow(e.Node);
            }
            catch (Exception ex)
            {
                LogEvent(ex);
            }
        }

        private void _ctlExplorerTree_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            try
            {
                ExpandSubNodes(e.Node);
            }
            catch (Exception ex)
            {
                LogEvent(ex);
            }
        }

        // SvdO: KeyPress didn't work, KeyUp used instead
        private void _ctlExplorerTree_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                if (_ctlExplorerTree.SelectedNode == null) return;
                XmlElement oItemXml = (XmlElement) _ctlExplorerTree.SelectedNode.Tag;
                FileProperties p = new FileProperties(_ctlExplorerTree.SelectedNode);
                FolderProperties fp = new FolderProperties(_ctlExplorerTree.SelectedNode);
                if (e.KeyCode == Keys.Delete)
                {
                    if (oItemXml.Name == "File")
                    {
                        mnuDeleteFile_Click(null, null);
                        LogEvent(2, "Deleted file: " + p.Url);
                    }
                    if (oItemXml.Name == "Folder")
                    {
                        mnuDeleteFolder_Click(null, null);
                        LogEvent(2, "Deleted folder: " + p.Url);
                    }
                }
                else if (e.KeyCode == Keys.F2)
                {
                    _ctlExplorerTree.SelectedNode.BeginEdit();
                }
                else if (e.KeyCode == Keys.F5)
                {
                    if (oItemXml.Name == "File")
                    {
                        // Refresh the parent folder, make current node current again
                        if (_ctlExplorerTree.SelectedNode.Parent != null)
                        {
                            RefreshFolder(_ctlExplorerTree.SelectedNode.Parent, _ctlExplorerTree.SelectedNode.Text);
                        }
                    }
                    else
                    {
                        // Refresh the folder
                        RefreshFolder(_ctlExplorerTree.SelectedNode);
                    }
                }
            }
            catch (Exception ex)
            {
                LogEvent(ex);
            }
        }

        // SvdO: Can be new folder, new file, rename folder or rename file. Even if no edit of label, 
        //       can still be that "New Folder" or "NewFile1.txt" is added. Refresh the parent node.
        private void _ctlExplorerTree_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            try
            {
                // Changes were made to label
                if (e.Label != null)
                {
                    XmlElement oItemXml = (XmlElement) e.Node.Tag;

                    if (oItemXml.Name == "Folder")
                    {
                        FolderProperties fp = new FolderProperties(e.Node);
                        try
                        {
                            DevServices(e.Node).RenameFolder(fp.ID, e.Label);
                            fp.Xml.SetAttribute("Name", e.Label);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(String.Format("It is not possible to rename folder '{0}' to '{1}'.\n\n{2}", e.Node.Text, e.Label, ex.Message), "Rename Folder");
                        }
                    }
                    else
                    {
                        FileProperties p = new FileProperties(e.Node);
                        try
                        {
                            string renamedFileXml = DevServices(e.Node).RenameFile(p.Url, e.Label);
                            ReplaceFileNode(p, renamedFileXml);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(String.Format("It is not possible to rename file '{0}' to '{1}'.\n\n{2}", e.Node.Text, e.Label, ex.Message), "Rename File");
                        }
                    }

                    // Update the details of the parent (folder) node, and make the edit node current again. Do this by searching on name, because
                    // the tree is refreshed, and all child nodes are killed
                    if (e.Node.Parent != null)
                    {
                        RefreshFolder(e.Node.Parent, e.Label);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void _ctlExplorerTree_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            try
            {
                XmlElement oItemXml = (XmlElement) e.Node.Tag;

                if (oItemXml.Name == "Folder")
                {
                    FolderProperties fp = new FolderProperties(e.Node);
                    if (fp.ReadOnly) e.CancelEdit = true;
                    if (fp.IsDocumentLibrary) e.CancelEdit = true;
                    if (e.Node.Parent == null) e.CancelEdit = true;
                }
                else
                {
                    FileProperties p = new FileProperties(_ctlExplorerTree.SelectedNode);
                    if (!p.CanModify) e.CancelEdit = true;
                }
            }
            catch (Exception ex)
            {
                LogEvent(ex);
            }
        }

        private void ctxMenuFile_Opening(object sender, CancelEventArgs e)
        {
            try
            {
                FileProperties p = new FileProperties(_ctlExplorerTree.SelectedNode);

                if (p.HasCheckedOut)
                {
                    mnuSaveFile.Enabled = true;
                    mnuCheckInFile.Text = String.Format("Check In (Checked Out by {0})", p.CheckedOutBy);
                    mnuCheckInFile.Enabled = true;
                }
                else
                {
                    mnuSaveFile.Enabled = false;
                    mnuCheckInFile.Text = "Check In";
                    mnuCheckInFile.Enabled = false;
                }

                mnuCheckOutFile.Enabled = (!p.HasCheckedOut && p.CheckedOutBy == "");
                mnuUndoCheckOutFile.Enabled = p.HasCheckedOut;

                // SvdO: better control on publish
                FolderProperties fp = new FolderProperties(_ctlExplorerTree.SelectedNode.Parent);
                if (fp.EnableVersioning)
                {
                    if (!p.HasCheckedOut)
                    {
                        // File is checked in, it can be published
                        mnuPublishAndApproveFile.Text = "Publish and Appro&ve";
                        mnuPublishAndApproveFile.Enabled = true;
                        mnuPublishFile.Text = "P&ublish";
                        mnuPublishFile.Enabled = true;
                        if (fp.EnableModeration)
                        {
                            mnuApproveFile.Text = "&Approve";
                            mnuApproveFile.Enabled = true;
                        }
                        else
                        {
                            mnuApproveFile.Text = "&Approve (No moderation)";
                            mnuApproveFile.Enabled = false;
                        }
                    }
                    else
                    {
                        mnuPublishAndApproveFile.Text = "Publish And Appro&ve (Check-In first!)";
                        mnuPublishAndApproveFile.Enabled = false;
                        mnuPublishFile.Text = "P&ublish (Check-In first!)";
                        mnuPublishFile.Enabled = false;
                        if (fp.EnableModeration)
                        {
                            mnuApproveFile.Text = "&Approve (Check-In first!)";
                            mnuApproveFile.Enabled = false;
                        }
                        else
                        {
                            mnuApproveFile.Text = "&Approve (No moderation)";
                            mnuApproveFile.Enabled = false;
                        }
                    }
                }
                else
                {
                    mnuPublishAndApproveFile.Text = "Publish And Appro&ve (No versioning)";
                    mnuPublishAndApproveFile.Enabled = false;
                    mnuPublishFile.Text = "P&ublish (No versioning)";
                    mnuPublishFile.Enabled = false;
                    mnuApproveFile.Text = "&Approve (No moderation)";
                    mnuApproveFile.Enabled = false;
                }
            }
            catch (Exception ex)
            {
                LogEvent(ex);
            }
        }

        private void _ctlExplorerTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            try
            {
                _ctlExplorerTree.SelectedNode = e.Node;
                SetPropertiesWindow(e.Node);
            }
            catch (Exception ex)
            {
            }
        }

        private void _ctlExplorerTree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            try
            {
                if (!ServicesAllowed) return;

                XmlElement oItemXml = (XmlElement) e.Node.Tag;

                if (oItemXml == null) return;

                if (oItemXml.Name == "File")
                    OpenFile(e.Node);
            }
            catch (Exception ex)
            {
                LogEvent(ex);
            }
        }
    }
}